home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / Tool Chest / Development Platforms / AppsToGo / AppsToGo.src / DTS.Draw / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-18  |  13.8 KB  |  534 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Menu.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1990-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  26. #include "App.defs.h"        /* Get various application definitions.            */
  27. #include "App.protos.h"        /* Get the prototypes for application.            */
  28.  
  29. #ifndef __DESK__
  30. #include <Desk.h>
  31. #endif
  32.  
  33. #ifndef __ERRORS__
  34. #include <Errors.h>
  35. #endif
  36.  
  37. #ifndef __MEMORY__
  38. #include <Memory.h>
  39. #endif
  40.  
  41. #ifndef __MENUS__
  42. #include <Menus.h>
  43. #endif
  44.  
  45. #ifndef __TOOLUTILS__
  46. #include <ToolUtils.h>
  47. #endif
  48.  
  49. #ifndef __TREEOBJ2__
  50. #include "TreeObj2.h"
  51. #endif
  52.  
  53. #ifndef __UTILITIES__
  54. #include "Utilities.h"
  55. #endif
  56.  
  57.  
  58.  
  59. /*****************************************************************************/
  60.  
  61.  
  62.  
  63. extern Boolean    gQuitApplication;
  64. extern Boolean    gHasAppleEvents;
  65. extern OSType    gAppWindowType;
  66.  
  67. extern Boolean    gLowOnMem;
  68.  
  69.  
  70.  
  71. /*****************************************************************************/
  72. /*****************************************************************************/
  73.  
  74.  
  75.  
  76. /* •• Called by DTS.Lib..framework. •• */
  77.  
  78. /* Adjust the menu items.  We allow the DTS.Lib framework to do most of the work
  79. ** for us.  It will walk the menubar, and for each menu in the menubar, it will
  80. ** disable all of the menu items and then call the application at either
  81. ** AdjustMenuItems() (for document and palette windows, or for the no-window case),
  82. ** or DialogAdjustMenuItems() (for modal dialogs).  The application's job is to then
  83. ** turn on menu items that should be enabled to match the current application state.
  84. ** The initial Wannabe code for AdjustMenuItems() calls DoAdjustFileMenu() for the
  85. ** file menu, and DoAdjustEditMenu() for the edit menu.  Any other menus that may
  86. ** be added to Wannabe have all menu items enabled.  This allows menus to be added
  87. ** to the running version of Wannabe and allows them to actually do something.
  88. ** If the top-most window is a dialog, then all menus are disabled except for the
  89. ** edit menu.  Various items in the edit menu are enabled, depending on if there
  90. ** is an active TextEdit control, and what is in the clipboard. */
  91.  
  92. #pragma segment Menu
  93. void    DoAdjustMenus(void)
  94. {
  95.     if (DoAdjustMBARMenus(FrontWindow(), rMenuBar))
  96.         DrawMenuBar();
  97. }
  98.  
  99.  
  100.  
  101. /*****************************************************************************/
  102.  
  103.  
  104.  
  105. /* This is called when an item is chosen from the menu bar (after calling
  106. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  107. ** It is good to have both the result of MenuSelect and MenuKey go to one
  108. ** routine like this to keep everything organized. */
  109.  
  110. #pragma segment Menu
  111. Boolean    DoMenuCommand(short menuID, short menuItem)
  112. {
  113.     short        saveMode, daRefNum, i;
  114.     Str255        str;
  115.     FileRecHndl    frHndl, newFrHndl;
  116.     WindowPtr    window, clipWind;
  117.     TreeObjHndl    root, cobj;
  118.     OSErr        err;
  119.     Boolean        handled;
  120.  
  121.     handled = true;
  122.  
  123.     if (window = FrontWindowOfType(kwIsDocument, true))
  124.         frHndl = (FileRecHndl)GetWRefCon(window);
  125.             /* frHndl is valid only if it is one of our windows. */
  126.  
  127.     switch (menuID) {
  128.  
  129.         case mApple:
  130.             switch (menuItem) {
  131.                 case kStdAbout:        /* Bring up alert for About. */
  132.                     NewDocumentWindow(nil, 'ABOT', false);
  133.                     break;
  134.                 default:            /* All non-About items in this menu are DAs. */
  135.                     GetItem(GetMHandle(mApple), menuItem, str);
  136.                     daRefNum = OpenDeskAcc(str);
  137.                     break;
  138.             }
  139.             break;
  140.  
  141.         case mFile:
  142.             switch (menuItem) {
  143.                 case kStdNew:
  144.                     if (err = NewDocumentWindow(nil, gAppWindowType, true))
  145.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  146.                     break;
  147.                 case kStdOpen:
  148.                     err = OpenDocumentWindow(&frHndl, nil, fsRdWrPerm);
  149.                     if ((err) && (err != userCanceledErr))
  150.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  151.                     break;
  152.                 case kStdClose:
  153.                     DisposeOneWindow(window, kClose);
  154.                     break;
  155.                 case kStdSave:
  156.                 case kStdSaveAs:
  157.                     saveMode = (menuItem == kStdSave) ? kSave : kSaveAs;
  158.                     if ((*frHndl)->fileState.refNum == kInvalRefNum)
  159.                         saveMode = kSaveAs;
  160.                     err = SaveDocument(frHndl, window, saveMode);
  161.                     if ((err) && (err != userCanceledErr))
  162.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  163.                     break;
  164.                 case kDuplicate:
  165.                     err = DuplicateDocument(frHndl, &newFrHndl);
  166.                     if (!err) {
  167.                         err = DoNewWindow(newFrHndl, nil, FrontWindowOfType(kwIsDocument, true),
  168.                                           (WindowPtr)-1);
  169.                         if (err)
  170.                             DisposeDocument(newFrHndl);
  171.                     }
  172.                     if (err)
  173.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  174.                     break;
  175.                 case kStdPageSetup:
  176.                     DoSetCursor(&qd.arrow);
  177.                     PresentStyleDialog(frHndl);
  178.                     break;
  179.                 case kStdPrint:
  180.                     DoSetCursor(&qd.arrow);
  181.                     err = noErr;
  182.                     if (!(*frHndl)->d.doc.fhInfo.printRecValid)
  183.                         err = PresentStyleDialog(frHndl);
  184.                     if (!err) {
  185.                         err = PrintDocument(frHndl, true, true);
  186.                         PrintDocument(nil, false, false);
  187.                     }
  188.                     if ((err) && (err != userCanceledErr))
  189.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  190.                     break;
  191.                 case kStdQuit:
  192.                     gQuitApplication = DisposeAllWindows();
  193.                     break;
  194.             }
  195.             break;
  196.  
  197.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  198.             if (!IsDAWindow(window)) {
  199.                 if (menuItem == kClipboard) {
  200.                     clipWind = GetNextWindow(nil, kClipboardFileType);
  201.                     if (clipWind) {
  202.                         ShowHide(clipWind, !((WindowPeek)clipWind)->visible);
  203.                         CleanSendInFront(clipWind, FrontWindowOfType(kwIsDocument, false));
  204.                     }
  205.                     break;
  206.                 }
  207.                 if (menuItem == kStdViewHier) {
  208.                     handled = false;        /* Let framework automatically open the view hierarchy window. */
  209.                     break;
  210.                 }
  211.                 switch ((*frHndl)->fileState.sfType) {
  212.                     case kDocFileType:
  213.                         switch (menuItem) {
  214.                             case kStdUndo:
  215.                             case kStdRedo:
  216.                                 DoUndoTask((*frHndl)->d.doc.root, menuItem - kStdUndo, true);
  217.                                 break;
  218.                             case kStdCut:
  219.                             case kStdCopy:
  220.                             case kStdPaste:
  221.                                 DoClipboard(frHndl, menuItem);
  222.                                 break;
  223.                             case kStdClear:
  224.                                 DoDelete(frHndl);
  225.                                 break;
  226.                             case kSelectAll:
  227.                                 BeginContent(window);
  228.                                 root = (*frHndl)->d.doc.root;
  229.                                 for (i = (*root)->numChildren; i;) {
  230.                                     cobj = GetChildHndl(root, --i);
  231.                                     DoTreeObjMethod(cobj, SETSELECTMESSAGE, SELECTON);
  232.                                 }
  233.                                 EndContent(window);
  234.                                 break;
  235.                             default:
  236.                                 handled = false;
  237.                         }
  238.                         break;
  239. #if VH_VERSION
  240.                     case kViewHierFileType:
  241.                         BeginContent(window);
  242.                         switch (menuItem) {
  243.                             case kStdUndo:
  244.                                 CTEUndo();
  245.                                 break;
  246.                             case kStdCut:
  247.                             case kStdCopy:
  248.                             case kStdPaste:
  249.                             case kStdClear:
  250.                                 CTEClipboard(menuItem - kStdCut + 2);
  251.                                 break;
  252.                         }
  253.                         EndContent(window);
  254.                         break;
  255. #endif
  256.                 }
  257.             }
  258.             else SystemEdit(menuItem - 1);
  259.             break;
  260.  
  261.         case mArrange:
  262.             DoArrange(frHndl, menuItem);
  263.             break;
  264.  
  265.         case mOther:
  266.             switch (menuItem) {
  267.                 case kPenSize:
  268.                     NewDocumentWindow(&frHndl, 'PENS', false);
  269.                     break;
  270.                 case kBorderColor:
  271.                 case kContentColor:
  272.                     ChangeColor(frHndl, window, menuItem);
  273.                     break;
  274.             }
  275.             break;
  276.  
  277.         case mToolPalette:
  278.             switch (menuItem) {
  279.                 case -1:
  280.                     handled = false;
  281.                     break;
  282.                 default:
  283.                     SetPaletteTool(menuItem - 1);
  284.                     break;
  285.             }
  286.  
  287.         default:
  288.             handled = false;
  289.             break;
  290.     }
  291.  
  292.     return(handled);
  293. }
  294.  
  295.  
  296.  
  297. /*****************************************************************************/
  298.  
  299.  
  300.  
  301. #pragma segment Menu
  302. Boolean    DoAdjustFileMenu(WindowPtr window)
  303. {
  304.     MenuHandle    menu;
  305.     FileRecHndl    frHndl;
  306.     short        enableItem;
  307.  
  308.     menu = GetMHandle(mFile);
  309.  
  310.     EnableItem(menu, UnmapMItem(mFile, kStdQuit));            /* Gotta be able to quit. */
  311.  
  312.     if (IsDAWindow(window)) {
  313.         EnableItem(menu, UnmapMItem(mFile, kStdClose));        /* Let DAs do a close from the menu. */
  314.         return(false);
  315.     }
  316.  
  317.     if (!gLowOnMem) {
  318.         EnableItem(menu, UnmapMItem(mFile, kStdNew));
  319.         EnableItem(menu, UnmapMItem(mFile, kStdOpen));
  320.     }
  321.  
  322.     if (window = FrontWindowOfType(kwIsDocument, true)) {
  323.         EnableItem(menu, UnmapMItem(mFile, kStdClose));
  324.         frHndl = (FileRecHndl)GetWRefCon(window);
  325.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  326.             enableItem = GetWindowDirty(window);
  327.             if ((*frHndl)->fileState.refNum == kInvalRefNum)
  328.                 enableItem = true;
  329.             if (enableItem)
  330.                 EnableItem(menu, UnmapMItem(mFile, kStdSave));
  331.             EnableItem(menu, UnmapMItem(mFile, kStdSaveAs));
  332.             EnableItem(menu, UnmapMItem(mFile, kDuplicate));
  333.         }
  334.         EnableItem(menu, UnmapMItem(mFile, kStdPageSetup));
  335.         EnableItem(menu, UnmapMItem(mFile, kStdPrint));
  336.     }
  337.  
  338.     return(false);
  339. }
  340.  
  341.  
  342.  
  343. /*****************************************************************************/
  344.  
  345.  
  346.  
  347. #pragma segment Menu
  348. Boolean    DoAdjustEditMenu(WindowPtr window)
  349. {
  350.     MenuHandle        menu;
  351.     Boolean            menuEnabled;
  352.     FileRecHndl        frHndl, frClip;
  353.     WindowPtr        clipWind;
  354.     short            i, undoDepth, numUndos;
  355.     Boolean            haveDocument;
  356.     Str255            str;
  357.     StringPtr        cptr;
  358.     TreeObjHndl        root;
  359.     static Str32    clipboardText[3];
  360.  
  361.     menu = GetMHandle(mEdit);
  362.  
  363.     if (IsDAWindow(window)) {
  364.         EnableItem(menu, UnmapMItem(mEdit, kStdUndo));
  365.         EnableItem(menu, UnmapMItem(mEdit, kStdCut));
  366.         EnableItem(menu, UnmapMItem(mEdit, kStdCopy));
  367.         EnableItem(menu, UnmapMItem(mEdit, kStdPaste));
  368.         EnableItem(menu, UnmapMItem(mEdit, kStdClear));
  369.         return(false);
  370.     }
  371.  
  372.     haveDocument = (window = FrontWindowOfType(kwIsDocument, true)) ? true : false;
  373.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  374.  
  375. #if VH_VERSION
  376.     if (haveDocument)
  377.         EnableItem(menu, UnmapMItem(mEdit, kStdViewHier));
  378. #endif
  379.  
  380.     EnableItem(menu, UnmapMItem(mEdit, kClipboard));
  381.     if (!clipboardText[0][0]) {
  382.         GetItem(menu, UnmapMItem(mEdit, kClipboard), str);
  383.         p2c(str);
  384.         for (i = 0; str[i]; ++i)
  385.             if (str[i] == ',')
  386.                 str[i] = 0;
  387.         for (cptr = str, i = 0; i < 3; ++i) {
  388.             c2p((char *)cptr);
  389.             pcpy(clipboardText[i], cptr);
  390.             cptr += (cptr[0] + 1);
  391.         }
  392.     }
  393.     if (clipWind = GetNextWindow(nil, kClipboardFileType)) {
  394.         i = (((WindowPeek)clipWind)->visible) ? 1 : 0;
  395.         pcpy(str, clipboardText[i]);
  396.         pcat(str, clipboardText[2]);
  397.         SetItem(menu, UnmapMItem(mEdit, kClipboard), str);
  398.     }
  399.  
  400.     if (haveDocument) {
  401.         root = (*frHndl)->d.doc.root;
  402.         switch ((*frHndl)->fileState.sfType) {
  403.             case kDocFileType:
  404.                 GetUndoInfo(frHndl, &undoDepth, &numUndos);
  405.                 if (undoDepth)
  406.                     EnableItem(menu, UnmapMItem(mEdit, kStdUndo));
  407.                 if (undoDepth < numUndos)
  408.                     EnableItem(menu, UnmapMItem(mEdit, kStdRedo));
  409.                 if (mDerefRoot(root)->numSelected) {
  410.                     EnableItem(menu, UnmapMItem(mEdit, kStdCut));
  411.                     EnableItem(menu, UnmapMItem(mEdit, kStdCopy));
  412.                     EnableItem(menu, UnmapMItem(mEdit, kStdClear));
  413.                 }
  414.                 if (clipWind) {
  415.                     frClip = (FileRecHndl)GetWRefCon(clipWind);
  416.                     if ((*((*frClip)->d.doc.root))->numChildren)
  417.                         EnableItem(menu, UnmapMItem(mEdit, kStdPaste));
  418.                 }
  419.                 if (mDerefRoot(root)->numSelected < (*root)->numChildren)
  420.                     EnableItem(menu, UnmapMItem(mEdit, kSelectAll));
  421.                 break;
  422. #if VH_VERSION
  423.             case kViewHierFileType:
  424.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  425.                                                  UnmapMItem(mEdit, kStdCut));
  426.                 break;
  427. #endif
  428.             default:
  429.                 EnableItem(menu, UnmapMItem(mEdit, kStdViewHier));
  430.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  431.                                                  UnmapMItem(mEdit, kStdCut));
  432.                 break;
  433.         }
  434.     }
  435.  
  436.     return(false);
  437. }
  438.  
  439.  
  440.  
  441. /*****************************************************************************/
  442.  
  443.  
  444.  
  445. #pragma segment Menu
  446. Boolean    DoAdjustArrangeMenu(WindowPtr window)
  447. {
  448.     MenuHandle        menu;
  449.     short            i, numChildren, numSelected, cnum, flag;
  450.     Boolean            haveDocument;
  451.     FileRecHndl        frHndl;
  452.     TreeObjHndl        root, chndl;
  453.  
  454.     if (IsDAWindow(window)) return(false);
  455.  
  456.     menu = GetMHandle(mArrange);
  457.  
  458.     haveDocument = (window = FrontWindowOfType(kwIsDocument, true)) ? true : false;
  459.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  460.  
  461.     for (i = kMoveForward; i <= kUngroup; ++i) CheckItem(menu, i, false);
  462.     if (haveDocument) {
  463.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  464.             root        = (*frHndl)->d.doc.root;
  465.             numChildren = (*root)->numChildren;
  466.             numSelected = mDerefRoot(root)->numSelected;
  467.             if (numSelected) {
  468.                 for (cnum = (*root)->numChildren; cnum;) {
  469.                     chndl = GetChildHndl(root, --cnum);
  470.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  471.                         if ((*chndl)->type == GROUPOBJ)
  472.                             EnableItem(menu, kUngroup);
  473.                 }
  474.             }
  475.             if ((numSelected) && (numChildren > 1)) {
  476.                 if ((flag = numSelected) == 1) {
  477.                     chndl = GetChildHndl(root, 0);
  478.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  479.                         --flag;
  480.                 }
  481.                 if (flag) {
  482.                     EnableItem(menu, kMoveForward);
  483.                     EnableItem(menu, kMoveToFront);
  484.                 }
  485.                 if ((flag = numSelected) == 1) {
  486.                     chndl = GetChildHndl(root, -1);        /* Last child. */
  487.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  488.                         --flag;
  489.                 }
  490.                 if (flag) {
  491.                     EnableItem(menu, kMoveBackward);
  492.                     EnableItem(menu, kMoveToBack);
  493.                 }
  494.             }
  495.             if (numSelected > 1)
  496.                 EnableItem(menu, kGroup);
  497.         }
  498.     }
  499.  
  500.     return(false);
  501. }
  502.  
  503.  
  504.  
  505. /*****************************************************************************/
  506.  
  507.  
  508.  
  509. #pragma segment Menu
  510. Boolean    DoAdjustOtherMenu(WindowPtr window)
  511. {
  512.     MenuHandle        menu;
  513.     Boolean            haveDocument;
  514.     FileRecHndl        frHndl;
  515.  
  516.     if (IsDAWindow(window)) return(false);
  517.  
  518.     menu = GetMHandle(mOther);
  519.  
  520.     haveDocument = (window = FrontWindowOfType(kwIsDocument, true)) ? true : false;
  521.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  522.  
  523.     if (haveDocument) {
  524.         EnableItem(menu, kPenSize);
  525.         EnableItem(menu, kBorderColor);
  526.         EnableItem(menu, kContentColor);
  527.     }
  528.  
  529.     return(false);
  530. }
  531.  
  532.  
  533.  
  534.